package com.gack.business.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gack.business.dao.StatisticalDao;
import com.gack.business.model.UseStatistical;
import com.gack.business.repository.JoinConferenceRecordRepository;
import com.gack.business.repository.OrderRepository;
import com.gack.business.repository.UseStatisticalRepository;
import com.gack.business.repository.UserRepository;
import com.gack.business.repository.VideoStoresRepository;
import com.gack.business.vo.IncomeStatistical;
import com.gack.business.vo.RegisterStatistical;
import com.gack.business.vo.StoresStatistical;
import com.gack.business.vo.StoresUseStatistical;
import com.gack.business.vo.VideoUseStatistical;
import com.gack.helper.common.abstractobj.Result;

@Service
public class IndexDataService implements IndexDataServiceInterface {
	@Autowired
	private UserRepository userRepository;
	@Autowired
	private VideoStoresRepository storesRepository;
	@Autowired
	private OrderRepository orderRepository;
	@Autowired
	private UseStatisticalRepository useStatisticalRepository;
	@Autowired
	private JoinConferenceRecordRepository joinConferenceRecordRepository;
	@Autowired
	private StatisticalDao statisticalDao;
	@PersistenceContext
	private EntityManager entityManager;
	
	/**
	 * 运营后台的首页基础数据<br/>
	 * 包括 用户注册总数，安卓注册数，iOS注册数，PC注册数，办公地点统计，用户使用视频会议次数统计，门店使用次数统计<br/>
	 * app使用量和下载量暂时不能使用，app使用量需要对接数极客，下载量不能统计。
	 */
	@Override
	public Map<String, Object> indexStatistical() {
		Map<String,Object> map = new HashMap<String,Object>();
		// 查询用户注册总数
		Long userRegTotalNumber = 0L;
		userRegTotalNumber = userRepository.selectByCountId();
		map.put("userRegTotalNumber", userRegTotalNumber);
		// 查询安卓注册用户
		Long androidRegNumber = 0L;
		androidRegNumber = userRepository.countByRegisterSource("android");
		/*List<User> androidUser = userRepository.findByRegisterSource("android");
		if (androidUser != null) {
			androidRegNumber = androidUser.stream().count();	
		}*/
		map.put("androidRegNumber", androidRegNumber);
		// 查询iOS注册用户
		Long iosRegNumber = 0L;
		iosRegNumber = userRepository.countByRegisterSource("ios");
		/*List<User> iosUser = userRepository.findByRegisterSource("ios");
		if (iosUser != null) {
			iosRegNumber = iosUser.stream().count();	
		}*/
		map.put("iosRegNumber", iosRegNumber);
		// 查询pc客户端注册用户
		Long pcRegNumber = 0L;
		pcRegNumber = userRepository.countByRegisterSource("pc");
		/*List<User> pcUser = userRepository.findByRegisterSource("pc");
		if (pcUser != null) {
			pcRegNumber = pcUser.stream().count();
		}*/
		map.put("pcRegNumber", pcRegNumber);
		// 办公地点统计
		Long storesTotal = 0L;
		storesTotal = storesRepository.countByIsUse(0);
		/*List<VideoStores> stores = storesRepository.findByIsUse(0);
		if (stores != null) {
			storesTotal = stores.stream().count();
		}*/
		map.put("storesTotal", storesTotal);
		// 下载量统计
		Long downloadTotal = 0L;
		map.put("downloadTotal", downloadTotal);
		// 用户使用视频会议次数统计
		Long videoConferenceTotal = 0L;
		videoConferenceTotal = joinConferenceRecordRepository.count();
		/*List<User> users = userRepository.findAll();
		if (users != null) {
			List<Integer> counts = users.stream().map(User::getJoinVideoNum).collect(Collectors.toList());
			int count = counts.stream().reduce(0, Integer::sum);
			videoConferenceTotal = Long.valueOf(count);
		
		}*/
		map.put("videoConferenceTotal", videoConferenceTotal);
		// 门店使用次数统计 查询订单状态为8，9，10
		Long storesConferenceTotal = 0L;
		storesConferenceTotal = orderRepository.countByStatusIn(Arrays.asList("8","9","10"));
		/*List<Order> orders = orderRepository.findByStatus();
		if (orders != null) {
			storesConferenceTotal = orders.stream().count();
		}*/
		map.put("storesConferenceTotal", storesConferenceTotal);
		Long appUseTotal = 0L;
		map.put("appUseTotal", appUseTotal);
		return map;
	}
	/**
	 * 使用数据（没有使用该代码）
	 */
	@Override
	public Result addStatistical(Integer useSource) {
		UseStatistical useStatistical = new UseStatistical();
		useStatistical.setUseSource(useSource);
		useStatistical.setUseTime(new Date());
		useStatisticalRepository.save(useStatistical);
		Result result = new Result();
		result.setKey("success");
		result.setValue("保存成功");
		return result;
	}
	
	/**
	 * 收入统计<br/>
	 * @param year 查询年份
	 */
	@Override
	public Map<String, Object> incomeStatistical(Integer year) {
		Map<String, Object> map = new HashMap<>();
		List<IncomeStatistical> incomeStatisticals = null;
		// 返回值 incomeList为收入集合，按照月份排序1～12
		List<Long> incomeList = new LinkedList<>();
		// 从一月份开始循环，12月
		for (int i = 1; i < 13; i++) {
			// 根据年，月查询
			incomeStatisticals = statisticalDao.findIncomeStatistical(year, i);
			// 如果查出数据，则添加到集合中
			if (incomeStatisticals != null && incomeStatisticals.size() >0) {
				IncomeStatistical incomeStatistical = incomeStatisticals.get(0);
				if (incomeStatistical != null) {
					// 把总数放入集合
					incomeList.add(incomeStatistical.getTotal());
				} else {
					// 如果为空，用0补位
					incomeList.add(0L);
				}
			} else {
				// 没有数据，用0补位
				incomeList.add(0L);
			}
		}
		map.put("incomeList", incomeList);
		// 2018年9.13修改新代码，以为为老代码，迭代稳定后可删除。
		/*String jpql = "SELECT new com.gack.business.vo.IncomeStatistical(date_format(o.endTime,'%m'),sum(o.amount) ) FROM Order o WHERE YEAR(o.endTime) =:year AND o.status IN(8,9,10) GROUP BY date_format(o.endTime,'%m')";
		Query query = entityManager.createQuery(jpql);
		query.setParameter("year", year);
		List<IncomeStatistical> incomeStatisticals = query.getResultList();
		List<Long> incomeList = new ArrayList<>();
		int j = 0;
		for (int i = 1; i < 13; i++) {
			if (j < incomeStatisticals.size()) {
				IncomeStatistical incomeStatistical = incomeStatisticals.get(j);
				if (incomeStatistical != null) {
					int month = Integer.parseInt(incomeStatistical.getMonths());
					if (month == i) {
						incomeList.add(incomeStatistical.getTotal());
						j++;
					} else {
						incomeList.add(0L);
					}
				}
				
			} else {
				incomeList.add(0L);
			}
		}
		map.put("incomeList", incomeList);*/
		return map;
	}
	/**
	 * 注册人数统计，根据月份，统计各个渠道的注册人数<br/>
	 * @param year 年份
	 * 分渠道统计 android iOS PC
	 */
	@Override
	public Map<String, Object> registerStatistical(Integer year) {
		Map<String, Object> map = new HashMap<>();
		// iOS注册总数集合
		List<Long> iosList = registerStatisticalByChannel(year, "ios");
		// android 注册总数集合
		List<Long> androidList = registerStatisticalByChannel(year, "android");
		// pc 注册总数集合
		List<Long> pcList = registerStatisticalByChannel(year, "pc");
		
		map.put("iosList", iosList);
		map.put("androidList", androidList);
		map.put("pcList", pcList);
		
		// 2018年9.13修改新代码，以为为老代码，迭代稳定后可删除。
		//select date_format(createtime,'%m'),register_source,count(id) from user where date_format(createtime,'%Y')='2018' group by date_format(createtime,'%m'),register_source order by  date_format(createtime,'%m')
		/*String jpqlIos = "SELECT new com.gack.business.vo.RegisterStatistical(date_format(u.createtime,'%m'),count(id)) FROM User u WHERE YEAR(u.createtime) =:year AND u.registerSource='ios'  GROUP BY date_format(u.createtime,'%m')";
		Query queryIos = entityManager.createQuery(jpqlIos);
		queryIos.setParameter("year", year);
		List<RegisterStatistical> incomeStatisticalsIos = queryIos.getResultList();
		List<Long> iosList = new ArrayList<>();
		int j = 0;
		for (int i = 1; i < 13; i++) {
			if (j < incomeStatisticalsIos.size()) {
				RegisterStatistical registerStatistical = incomeStatisticalsIos.get(j);
				if (registerStatistical != null) {
					int month = Integer.parseInt(registerStatistical.getMonths());
					if (month == i) {
						iosList.add(registerStatistical.getRegisterTotal());
						j++;
					} else {
						iosList.add(0L);
					}
				}
			} else {
				iosList.add(0L);
			}
		}
		map.put("iosList", iosList);
		String jpqlAndroid = "SELECT new com.gack.business.vo.RegisterStatistical(date_format(u.createtime,'%m'),count(id)) FROM User u WHERE YEAR(u.createtime) =:year AND u.registerSource='android'  GROUP BY date_format(u.createtime,'%m')";
		Query queryAndroid = entityManager.createQuery(jpqlAndroid);
		queryAndroid.setParameter("year", year);
		List<RegisterStatistical> incomeStatisticalsAndroid = queryAndroid.getResultList();
		List<Long> androidList = new ArrayList<>();
		int z = 0;
		for (int i = 1; i < 13; i++) {
			if (z < incomeStatisticalsAndroid.size()) {
				RegisterStatistical registerStatistical = incomeStatisticalsAndroid.get(z);
				if (registerStatistical != null) {
					int month = Integer.parseInt(registerStatistical.getMonths());
					if (month == i) {
						androidList.add(registerStatistical.getRegisterTotal());
						z++;
					} else {
						androidList.add(0L);
					}
				}
			} else {
				androidList.add(0L);
			}
		}
		map.put("androidList", androidList);*/
		
		return map;
	}
	/**
	 * 门店办公地点统计
	 */
	@Override
	public Map<Object, Object> storesStatistical() {
		Map<Object, Object> storesStatisticals = new HashMap<>();
		List<Object> list = new ArrayList<>();
		String jpql = "SELECT new com.gack.business.vo.StoresStatistical(s.area,count(id)) FROM VideoStores s WHERE s.isUse != 1 GROUP BY s.area ";
		Query query = entityManager.createQuery(jpql);
		List<StoresStatistical> statisticals = query.getResultList();
		for (StoresStatistical storesStatistical : statisticals) {
			Map<Object, Object> store = new HashMap<>();
			store.put("value", storesStatistical.getTotal());
			store.put("name", storesStatistical.getArea());
			list.add(store);
			
		}
		storesStatisticals.put("success", list);
		return storesStatisticals;
	}
	/**
	 * 按照日期查询门店使用情况
	 * @param date 查询日期 eg:2018-09-14
	 */
	@Override
	public Map<String, Object> storesUseStatistical(String date) {
		List<StoresUseStatistical> storesUseStatisticals = null;
		List<Long> totals = new LinkedList<>();
		// 按照一天24小时循环
		for (int i = 0; i < 24; i++) {
			// 按照日期，小时查询门店使用情况
			storesUseStatisticals = statisticalDao.findStoresUseStatistical(date, i);
			if (storesUseStatisticals != null && storesUseStatisticals.size() >0) {
				StoresUseStatistical storesUseStatistical = storesUseStatisticals.get(0);
				if (storesUseStatistical != null) {
					// 查到数据添加到返回集合
					totals.add(storesUseStatistical.getTotal());
				} else {
					// 查不到用0 补位
					totals.add(0L);
				}
			} else {
				// 查不到用0 补位
				totals.add(0L);
			}
			
		}
/*		String jpql = "SELECT new com.gack.business.vo.StoresUseStatistical(date_format(o.beginTime,'%H'),count(id)) FROM Order o WHERE  o.status NOT IN (1,2,3) AND date_format(o.beginTime,'%Y-%m-%d')=:date group by date_format(o.beginTime,'%H')";
		Query query = entityManager.createQuery(jpql);
		query.setParameter("date", date);
		List<StoresUseStatistical> statisticals = query.getResultList();
		List<Long> totals = new ArrayList<>();
		int j = 0;
		for (int i = 0; i <=23; i++) {
			if (j < statisticals.size()) {
				StoresUseStatistical statistical = statisticals.get(j);
				if (statistical != null) {
					int time = Integer.parseInt(statistical.getTime());
					if (time == i) {
						totals.add(statistical.getTotal());
						j++;
					} else {
						totals.add(0L);
					}
				}
			} else {
				totals.add(0L);
			}
			
		}*/
		Map<String, Object> map = new HashMap<>();
 		map.put("totals", totals);
		return map;
	}

	/**
	 * 按照日期，查询视频会议使用情况
	 * @param date 查询日期 eg:2018-09-14
	 */
	@Override
	public Map<String, Object> videoUseStatistical(String date) {
		List<Long> appTotal = VideoUseStatisticalByChannel(date, 1);
		List<Long> iosTotal = VideoUseStatisticalByChannel(date, 2);
		List<Long> phoneTotal = new LinkedList<>();
		for (int i = 0; i < 24; i++) {
			phoneTotal.add(appTotal.get(i) + iosTotal.get(i));
		}
		List<Long> pcTotal = VideoUseStatisticalByChannel(date, 3);
	
/*		String jpql = "SELECT new com.gack.business.vo.VideoUseStatistical(date_format(j.joinTime,'%H'),count(id)) FROM JoinConferenceRecord j WHERE date_format(j.joinTime,'%Y-%m-%d')=:date group by date_format(j.joinTime,'%H')";
		Query query = entityManager.createQuery(jpql);
		query.setParameter("date", date);
		List<VideoUseStatistical> videoUseStatisticals = query.getResultList();
		List<Long> totals = new ArrayList<>();
		int j = 0;
		for (int i = 0; i <=23; i++) {
			if (j < videoUseStatisticals.size()) {
				VideoUseStatistical statistical = videoUseStatisticals.get(j);
				if (statistical != null) {
					int time = Integer.parseInt(statistical.getTime());
					if (time == i) {
						totals.add(statistical.getTotal());
						j++;
					} else {
						totals.add(0L);
					}
				}
			} else {
				totals.add(0L);
			}
			
		}*/
		Map<String, Object> map = new HashMap<>();
		map.put("phoneTotal", phoneTotal);
		map.put("pcTotal", pcTotal);
		return map;
	}
	/**
	 * 按照渠道查询注册总人数
	 * @param year 年
	 * @param channel 渠道
	 */
	@Override
	public List<Long> registerStatisticalByChannel(Integer year, String channel) {
		// 返回结果
		List<Long> resultList = new LinkedList<>();
		List<RegisterStatistical> registerStatisticals = null;
		// 按照月份循环，一共12个月
		for (int i = 1; i < 13; i++) {
			// 按照年份，循环的月份，渠道查询
			registerStatisticals = statisticalDao.findRegisterStatistical(year, i, channel);
			if (registerStatisticals != null && registerStatisticals.size() >0) {
				// 如果查询结果有值，则取total
				RegisterStatistical registerStatistical = registerStatisticals.get(0);
				if (registerStatistical != null) {
					resultList.add(registerStatistical.getRegisterTotal());
				} else {
					// 0 补位
					resultList.add(0L);
				}
			} else {
				// 没值用0 补位
				resultList.add(0L);
			}
		}
		return resultList;
	}
	@Override
	public List<Long> VideoUseStatisticalByChannel(String date, Integer channel) {
		List<VideoUseStatistical> videoUseStatisticals = null;
		List<Long> totals = new LinkedList<>();
		// 按照一天24小时循环
		for (int i = 0; i < 24; i++) {
			// 根据日期，小时 查询视频会议使用情况
			videoUseStatisticals = statisticalDao.findVideoUseStatistical(date, i, channel);
			if (videoUseStatisticals != null && videoUseStatisticals.size() >0) {
				VideoUseStatistical useStatistical = videoUseStatisticals.get(0);
				// 如果查询到了数据，添加到返回的集合中
				if (useStatistical != null) {
					totals.add(useStatistical.getTotal());
				} else {
					// 查不到用0补位
					totals.add(0L);
				}
			} else {
				// 查不到用0 补位
				totals.add(0L);
			}
			
		}
		return totals;
	}

}
